package com.bwstudio.demo.consumer.controller;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import com.bwstudio.demo.provider.api.DelaySimulateService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class BenchmarkController {

	@Reference
	DelaySimulateService delaySimulateService;
	
	@GetMapping(value = "/sync")
	public String testSync(@RequestParam long delay) {
	    return delaySimulateService.delay(delay);
	}

	/**
	 * 控制器异步 + 服务层同步 
	 * 高并发响应时间未得到优化
	 */
	@GetMapping("/deferredresult-with-dubbo-sync")
	public DeferredResult<String> testSync2(
			@RequestParam(required = true) Long delay, 
			@RequestParam(required = false, defaultValue = "5000") Long timeout) {
		DeferredResult<String> deferredResult = new DeferredResult<>(timeout);
		deferredResult.setResult(delaySimulateService.delay(delay));
		return deferredResult;
	}
	
	/**
	 * 控制器异步 + 服务层异步 
	 * 高并发响应时间得到优化
	 */
	@GetMapping("/deferredresult-with-dubbo-async")
	public DeferredResult<String> testSync3(
			@RequestParam(required = true) Long delay, 
			@RequestParam(required = false, defaultValue = "5000") Long timeout) {
		DeferredResult<String> deferredResult = new DeferredResult<>(timeout);
		// 异步调用
		CompletableFuture<String> doThirdFuture = delaySimulateService.asyncDelay(delay);

		doThirdFuture.whenComplete((result, throwable) -> {
			if (throwable != null) {
				throwable.printStackTrace();
			} else {
				deferredResult.setResult(result);
			}
		});
		
		return deferredResult;
	}
	
	/**
	 * 控制器异步 + 服务层异步
	 * 高并发响应时间得到优化
	 */
	@GetMapping(value = "/completable-future-with-dubbo-async")
	public CompletableFuture<String> testSync4(@RequestParam long delay) {
		return delaySimulateService.asyncDelay(delay);
	}
}
